package com.powernode.aspect;

import cn.hutool.json.JSONUtil;
import com.powernode.anno.Log;
import com.powernode.domain.SysLog;
import com.powernode.domain.SysUser;
import com.powernode.mapper.SysLogMapper;
import com.powernode.mapper.SysUserMapper;
import com.powernode.utils.AuthUtil;
import com.powernode.utils.ManagerThreadPool;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect
public class LogAspect {

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysLogMapper sysLogMapper;

    @Around(value = "@annotation(com.powernode.anno.Log)")
    public Object logAround(ProceedingJoinPoint joinPoint) {

        Object obj = null;

        // 获取目标方法参数
        Object[] args = joinPoint.getArgs();

        // 获取目标方法的对象
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();

        // 获取目标方法的名称
        String methodName = method.getName();

        // 获取目标方法上的注解
        Log annotation = method.getAnnotation(Log.class);

        // 获取注解的属性
        String operation = annotation.operation();

        // 获取ip地址
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();

        String remoteHost = requestAttributes.getRequest().getRemoteHost();

        // 开始时间
        long start = System.currentTimeMillis();

        // 执行目标方法

        try {
            obj = joinPoint.proceed(args);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        // 结束时间
        long end = System.currentTimeMillis();

        // 方法执行时长
        long execTime = end -start;

        // 获取用户的id
        String loginUserId = AuthUtil.getLoginUserId();

        // 创建多线程
        ManagerThreadPool.poolExecutor.execute(() -> {

            // 根据用户标识查询用户信息
            SysUser sysUser = sysUserMapper.selectById(loginUserId);

            // 创建操作行为日志对象
            SysLog sysLog = SysLog.builder()
                    .createDate(new Date())
                    .ip(remoteHost)
                    .method(methodName)
                    .operation(operation)
                    .time(execTime)
                    .params(args != null && args.length > 0 ? JSONUtil.toJsonStr(args) : "")
                    .username(sysUser.getUsername()).build();

            // 插入行为日志
            sysLogMapper.insert(sysLog);
        });

        return obj;
    }
}
